
package Service;

import model.Student;
import model.Course;
import model.Score;
import model.Teacher;
import exception.ScoreException;

import java.util.*;

public class GradeManagementSystem {
    private Map<String, Student> students = new HashMap<>();  // 学号->学生映射
    private Map<String, Course> courses = new HashMap<>();    // 课程编号->课程映射
    private List<Score> scores = new ArrayList<>();             // 成绩列表
    private Map<String, Teacher> teachers = new HashMap<>();  // 教师ID->教师映射

    /**
     * Manually add student, teacher, and course data
     */
    public void addStudent(String id, String name, String password, String clazz) {
        students.put(id, new Student(id, name, password, clazz));
    }

    public void addTeacher(String id, String name, String password, String title) {
        teachers.put(id, new Teacher(id, name, password, title));
    }

    public void addCourse(String code, String name, int credit) {
        courses.put(code, new Course(code, name, credit));
    }

    public void addScore(Student student, Course course, double score) throws ScoreException {
        if (score < 0 || score > 100) {
            throw new ScoreException("成绩超出有效范围！");
        }
        scores.add(new Score(student, course, score));
    }

    // Getters for students, courses, teachers, and scores
    public Map<String, Student> getStudents() {
        return students;
    }

    public Map<String, Course> getCourses() {
        return courses;
    }

    public List<Score> getScoresByCourse(Course course) {
        List<Score> courseScores = new ArrayList<>();
        for (Score score : scores) {
            if (score.getCourse().equals(course)) {
                courseScores.add(score);
            }
        }
        return courseScores;
    }

    public Map<String, Teacher> getTeachers() {
        return teachers;
    }

    public double convertScoreToGradePoint(double score) {
        if (score >= 90) return 4.0;
        if (score >= 85) return 3.7;
        if (score >= 82) return 3.3;
        if (score >= 78) return 3.0;
        if (score >= 75) return 2.7;
        if (score >= 72) return 2.3;
        if (score >= 68) return 2.0;
        if (score >= 64) return 1.5;
        if (score >= 60) return 1.0;
        return 0.0;
    }

    public double calculateGPA(Student student) {
        double totalPoints = 0.0;
        double totalCredits = 0.0;

        for (Score scoreRecord : scores) {
            if (scoreRecord.getStudent().equals(student)) {
                Course course = scoreRecord.getCourse();
                double gradePoint = convertScoreToGradePoint(scoreRecord.getScore());
                totalPoints += gradePoint * course.getCredit();
                totalCredits += course.getCredit();
            }
        }

        return totalCredits > 0 ? totalPoints / totalCredits : 0.0;
    }
}
